#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>

#include <QDebug>
#include <QTime>
#include <QDate>

#include <QFileDialog>
#include <QPushButton>

#include <QJsonDocument>
#include <QJsonObject>
#include <QTextStream>

// 调用了基类QMainWindow的构造函数，并通过ui(new Ui::MainWindow)来创建一个新的Ui::MainWindow对象。
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
    // 调用ui对象的setupUi函数，将用户界面与MainWindow类关联起来
    ui->setupUi(this);

    // 菜单栏设计和实现
    QMenuBar *peMenuBar = menuBar();
    QMenu *peMenuBarFile = new QMenu("文件(F)");  // 文件F
    QMenu *peMenuBarEdit = new QMenu("编辑(E)");  // 编辑E
    QMenu *peMenuBarOther = new QMenu("其他(O)"); // 其他B

    peMenuBar->addMenu(peMenuBarFile);
    peMenuBar->addMenu(peMenuBarEdit);
    peMenuBar->addMenu(peMenuBarOther);

    peMenuBarFile->addAction("打开文件", this, &MainWindow::openFile);

    pen = new QPen();
    pen->setCapStyle(Qt::PenCapStyle::RoundCap);   //圆角
    pen->setWidth(2);                              //粗细
    pen->setStyle(Qt::PenStyle::SolidLine);

    mx = my = 0;
    pen_shape = 0;

    pix = nullptr;
    pix_new = nullptr;
}

MainWindow::~MainWindow(){
    delete ui;
}


void MainWindow::openFile()
{
    QString fileName = QFileDialog::getOpenFileName(this, "Open File", QDir::homePath(), "All Files (*.*);;Text Files (*.txt)");

    if (!fileName.isEmpty()) {
        QFile file(fileName);
        if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {

            QTextStream stream(&file);
            QString content = stream.readAll();
            file.close();

            QJsonDocument doc = QJsonDocument::fromJson(content.toUtf8());
            if (!doc.isNull() && doc.isObject()) {
                QJsonObject obj = doc.object();

                resolution = obj.value("resolution").toDouble();     // 地图分辨率
                mapOriginX = obj.value("map_origin_x").toDouble();   // 地图原始x坐标
                mapOriginY = obj.value("map_origin_y").toDouble();   // 地图原始y坐标

                int numXCells = obj.value("num_x_cells").toInt();           // 地图宽度
                int numYCells = obj.value("num_y_cells").toInt();           // 地图高度

                qDebug() << "resolution:" << resolution;
                qDebug() << "map_origin_x:" << mapOriginX;
                qDebug() << "map_origin_y:" << mapOriginY;
                qDebug() << "num_x_cells:" << numXCells;
                qDebug() << "num_y_cells:" << numYCells;

                QFileInfo fileInfo(file.fileName());
                this->folderPath = fileInfo.absolutePath();
                qDebug() << "Folder Path:" << folderPath;

                // 初始化画布大小
                pix = new QPixmap(numXCells, numYCells);   //画布大小
                pix->fill(Qt::white);         //画布填充白色

                pix_new = new QPixmap(numXCells, numYCells);
                pix_new->fill(Qt::white);
                update();

            } else {
                qDebug() << "Failed to parse json from file:" << fileName;
            }

            qDebug() << content;
            file.close();
        } else {
            qDebug() << "Failed to open file:" << fileName;
        }
    } else {
        qDebug() << "User canceled the selection.";
    }
}

// 返回按钮
void MainWindow::on_btn_Exit_clicked()
{
 qDebug() << "已返回";
}

// 删除按钮
void MainWindow::on_btn_delete_clicked(){
    QMessageBox::StandardButton msg;    //弹窗
    msg = QMessageBox::question(this,"提醒","真的要删除吗?",QMessageBox::No | QMessageBox::Yes);
    if(msg == QMessageBox::No){
        qDebug() << "已取消";
        return;
    }
    mPoints.clear();
    pix->fill(Qt::white);         //画布填充白色
    update();
    qDebug() << "已删除";
}

bool savePixmapAsPGM(const QPixmap& pixmap, const QString& fileName)
{
    QImage image = pixmap.toImage().convertToFormat(QImage::Format_Grayscale8);

    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly)){
        qDebug() << "Failed to open file:" << fileName;
        return false;
    }

    QTextStream stream(&file);
    stream << "P2\n";
    stream << image.width() << " " << image.height() << "\n";
    stream << "255\n";

    for (int y = 0; y < image.height(); ++y){
        for (int x = 0; x < image.width(); ++x){
            if(qGray(image.pixel(x, y)) > 200)
                stream << QString::number(0) << " ";
            else
                stream << QString::number(100) << " ";
        }
        stream << "\n";
    }

    file.close();

    qDebug() << "PGM file saved:" << fileName;
    return true;
}

QPointF MainWindow::gridToActualCoordinate(const QPoint& gridPoint)
{
    double actualX = this->mapOriginX + gridPoint.x() * this->resolution;
    double actualY = this->mapOriginY + gridPoint.y() * this->resolution;
    return QPointF(actualX, actualY);
}

// 保存按钮
void MainWindow::on_btn_Save_clicked(){
    QTime t = QTime::currentTime();
    QDate d = QDate::currentDate();
    // qDebug() << d.toString("yyyy-MM-dd");
    // qDebug() << t.toString("hh:mm:ss.zzz");

    bool saved = savePixmapAsPGM(*pix, folderPath + "/output.pgm");
    if (!saved){
        qDebug() << "Failed to save pixmap as PGM.";
    }

    QString time_p;
    time_p = time_p.append("%1%2%3%4").arg(folderPath + "/").arg(d.toString("yyyy-MM-dd_")).arg(t.toString("hh-mm-ss.zzz")).arg(".png");
    pix->save(time_p, "PNG");
    qDebug() << "已保存在: " + folderPath + " 目录下.....";

    // 创建一个 QFile 对象并打开文件（以写入模式）
    QFile pFile(folderPath + "/points.txt");
    if (pFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QTextStream pstream(&pFile);
        for (const auto& point : mPoints) {
            QPointF mfpoint = gridToActualCoordinate(point);
            pstream << mfpoint.x() << " " << mfpoint.y() << "\n";
        }
        pFile.close();
    }

    mPoints.clear();
}


// 绘图事件
void MainWindow::paintEvent(QPaintEvent *ev){
    if(!pix)
        return;

    ev->ignore();
    QPainter painter;
    painter.begin(this);
    this->mx = (width() - pix->width()) / 2;      // 计算图片左上角的 x 坐标
    this->my = (height() - pix->height()) / 2;    // 计算图片左上角的 y 坐标

    painter.drawPixmap(mx, my, *pix);
    painter.end();
}

// 鼠标按下事件
void MainWindow::mousePressEvent(QMouseEvent *ev){
    if(!pix || !pix_new)
        return;

    int mouseX = ev->x() - mx;  // 计算鼠标在图片中的 x 坐标
    int mouseY = ev->y() - my;  // 计算鼠标在图片中的 y 坐标

    qDebug() << "鼠标按下" << "x=" << mouseX << " y=" << mouseY;
    // ui->label_xy->setText("[x, y]: " + QString::number(ev->x()) + " " + QString::number(ev->y()));   //显示坐标
    ui->label_xy->setText("[x, y]: " + QString::number(mouseX) + " " + QString::number(mouseY));   //显示坐标

    *pix_new = pix->copy();  //在点击前
    //point = ev->pos();
    point.setX(ev->pos().x() - mx); // 设置新的 x 坐标
    point.setY(ev->pos().y() - my); // 设置新的 y 坐标
}

// 鼠标滑动事件
void MainWindow::mouseMoveEvent(QMouseEvent *ev){

    if(!pix || !pix_new)
        return;

    int mouseX = ev->x() - mx;  // 计算鼠标在图片中的 x 坐标
    int mouseY = ev->y() - my;  // 计算鼠标在图片中的 y 坐标

    ui->label_xy->setText("x=" + QString::number(mouseX) + " y=" + QString::number(mouseY));   //显示坐标
    QPainter painter;
    if(pen_shape == 1 || pen_shape == 2 || pen_shape == 3)
        *pix = pix_new->copy();

    painter.begin(pix);
    painter.setPen(*pen);
    if(ev->pos().y()<6)
        return;

    // painter.drawPoint(ev->x(),ev->y()-6);
    switch (pen_shape) {
    case 0:
        painter.drawLine(point.x(),point.y()-6,mouseX,mouseY-6);  //画线
        point.setX(ev->pos().x() - mx); // 设置新的 x 坐标
        point.setY(ev->pos().y() - my); // 设置新的 y 坐标
        mPoints.append(QPoint(mouseX,mouseY-6));
        break;
    case 1:
        painter.drawLine(point.x(),point.y()-6,mouseX,mouseY-6);  //直线
        mPoints.append(QPoint(mouseX,mouseY-6));
        break;
    case 2:
        painter.drawRect(point.x(),point.y()-6,mouseX-point.x(),mouseY-point.y());  //矩形
        mPoints.append(QPoint(mouseX-point.x(),mouseY-point.y()));
        break;
    case 3:
        painter.drawEllipse(point.x(),point.y()-6,mouseX-point.x(),mouseY-point.y());  //椭圆
        mPoints.append(QPoint(mouseX-point.x(),mouseY-point.y()));
        break;
    }
    painter.end();
    update();
}

// 鼠标松开事件
void MainWindow::mouseReleaseEvent(QMouseEvent *ev){
    if(!pix || !pix_new)
        return;

    int mouseX = ev->x() - mx;  // 计算鼠标在图片中的 x 坐标
    int mouseY = ev->y() - my;  // 计算鼠标在图片中的 y 坐标
    qDebug() << "鼠标松开" << "x=" << mouseX << " y=" << mouseY;
}


// 画笔
void MainWindow::on_btn_Pen_clicked(){
    qDebug() << "画笔";
    pen_shape = 0;
    pen->setColor(Qt::black);
    pen->setWidth(2);
    pen->setStyle(Qt::PenStyle::SolidLine);
}

// 橡皮擦
void MainWindow::on_btn_eraser_clicked()
{
    pen_shape = 0;
    qDebug() << "橡皮擦";
    pen->setWidth(20);
    pen->setColor(Qt::white);
}

// 直线事件
void MainWindow::on_btn_StraightLine_clicked(){
    qDebug() << "直线:";
    pen_shape = 1;
}

// 矩形工具
void MainWindow::on_btn_rectangle_clicked(){
    qDebug() << "矩形";
    pen_shape = 2;
}

// 椭圆工具
void MainWindow::on_btn_round_clicked(){
    qDebug() << "椭圆:";
    pen_shape = 3;
}























